package com.brozha.ans_sys.service.impl;

import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.brozha.ans_sys.entity.User;
import com.brozha.ans_sys.entity.vo.UserVO;
import com.brozha.ans_sys.exception.AnsSysException;
import com.brozha.ans_sys.mapper.UserMapper;
import com.brozha.ans_sys.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.brozha.ans_sys.utils.JWTUtil;
import com.brozha.ans_sys.utils.RedisUtils;
import com.brozha.ans_sys.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author brozha
 * @since 2021-04-04
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    RedisUtils redisUtils;


    /**
     * 通过key来查找redis里的user对象
     * @param key
     * @return
     */
    @Override
    public User getUserFromRedis(String key) {
        User user = null;
        Object obj = redisUtils.get(key);
        if(obj instanceof User){
            //如果是user类
            user = (User)obj;
        }
        return user;
    }

    @Override
    public Result regist(String username, String userpwd,String nickname,String avatarUrl) {

        //先在缓存中查找
        if(this.getUserFromRedis(username)!=null){
            //命中
            log.debug("缓存命中");
            throw new AnsSysException(-1,"注册失败，用户名重复！！！");
        }
        //如果缓存未命中
        log.debug("缓存未命中");
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("user_name",username);
        User user = this.getOne(userQueryWrapper);
        if(user!=null){
            //如果查到先存入缓存
            redisUtils.set(username,user,6);
            throw new AnsSysException(-1,"注册失败，用户名重复！！！");
        }
        //没查找到
        user = new User();
        user.setUserName(username);
        user.setUserPwd(userpwd);
        user.setNickname(nickname);
        user.setLevel(1);
        user.setScore(500L);
        user.setAvatar(avatarUrl);

        save(user);
        log.debug("完成注册");
        return Result.success("注册成功！！！");
    }

    @Override
    public Result login(String username, String userpwd) {

        //判断登录信息是否正确
        //在redis里查找username
        User user = this.getUserFromRedis(username);
        if(user==null){
            //缓存未命中
            log.debug("缓存未命中");
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.eq("user_name",username);
            user = this.getOne(userQueryWrapper);
        }
        if(user==null){
            throw new AnsSysException(-1,"用户名错误！！！");
        }
        //将该用户加入缓存，六天后失效
        redisUtils.set(username,user,6);
        //判断密码是否正确
        if(!userpwd.equals(user.getUserPwd())){
            throw new AnsSysException(-1,"密码错误！！！");
        }
        //判断用户是否已经登录
        if(redisUtils.hasKey(user.getUserName()+user.getId())){
            throw new AnsSysException(-1,"用户已经登录！！！");
        }
        //此时用户登录成功
        //生成jwt
        Map<String,String> map = new HashMap();
        map.put("id",user.getId());
        map.put("username",user.getUserName());
        String token = JWTUtil.getToken(map);
        //将id作为key存入redis，作为判断是否已经登录的依据
        redisUtils.set(user.getUserName()+user.getId(),1,5);
        //生成userVO
        UserVO userVO = new UserVO(user);

        return Result.successWithToken("登录成功！！！",userVO,token);
    }

    @Override
    public Result getInfo(String token) {
        DecodedJWT verify = JWTUtil.verify(token);
        String userid = verify.getClaim("id").asString();
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("id",userid);
        User user = this.getOne(qw);
        UserVO userVO = new UserVO(user);
        return Result.success("获得用户信息",userVO);
    }

    /**
     * 用户退出登录
     * @param token
     * @return
     */
    @Override
    public Result logOut(String token) {
        //查出用户id和name
        String id = JWTUtil.verify(token).getClaim("id").asString();
        String username = JWTUtil.verify(token).getClaim("username").asString();
        //删除redis里对应的字段======nameid
        redisUtils.del(username+id);
        return Result.success("退出登录成功！！！");
    }

    @Override
    public Result updateUser(String token, String userpwd, String nickname, String avatarUrl) {

        //查出用户id和name
        String id = JWTUtil.verify(token).getClaim("id").asString();
        //存入数据库
        UpdateWrapper<User> uw = new UpdateWrapper<>();
        uw.eq("id",id);
        User user = new User();
        user.setId(id);
        user.setUserPwd(userpwd);
        user.setAvatar(avatarUrl);
        user.setNickname(nickname);
        this.update(user,uw);
        //查找数据，更新redis
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("id",id);
        user = this.getOne(qw);
        redisUtils.set(user.getUserName(),user);
        UserVO userVO = new UserVO(user);
        return Result.success("修改成功！！！",userVO);
    }
}
